﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Newtonsoft.Json;

namespace CardsSimulator
{
    class Server : MessageTransmitter
    {
        public Socket ServerSocket;
        public List<Socket> ClientsSockets = new List<Socket>();

        public byte[] m_byBuff = new byte[655000];

        public Server()
        {
            ServerSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.IP);
            ServerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),1024));
            
            ServerSocket.Listen(1);

            try
            {
                for (int i = 0; i < CardGame.currentGame.NumberOfPlayers - 1; i++)
                {
                    ClientsSockets.Add(ServerSocket.Accept());

                    CardGame tempGame = CardGame.currentGame;
                    tempGame.currentPlayerId = i + 1;

                    var json = JsonConvert.SerializeObject(tempGame);

                    var netStream = new NetworkStream(ClientsSockets.Last(), true);
                    var bf = new BinaryFormatter();
                    var ms = new MemoryStream();
                    bf.Serialize(ms, json);
                    netStream.Write(ms.ToArray(), 0, ms.ToArray().Length);
                }
                CardGame.currentGame.Players.ElementAt(CardGame.currentGame.currentPlayerId).Transmitter = this;

                var recieveData = new AsyncCallback(OnRecieve);
                ServerSocket.BeginReceive(m_byBuff, m_byBuff.Length, 0, SocketFlags.None, recieveData, ServerSocket);

                MessageBox.Show("Pomyslnie nawiązano połaczenie z graczami", "Sukces");
            }
            catch (SocketException e)
            {
                MessageBox.Show("Przy nawiązywaniu połączenia z graczami nastąpił błąd", "Błąd");
            }

           
        }

        private void OnRecieve(IAsyncResult ar)
        {
            var socket = (Socket)ar.AsyncState;
            socket.EndReceive(ar);
            var stream = new NetworkStream(socket);
            var bf = new BinaryFormatter();
            stream.Flush();
            var json = (String)bf.Deserialize(stream);

            GameState move = JsonConvert.DeserializeObject<GameState>(json);
            CardGame.currentGame.AcceptMove(move);

            socket.BeginReceive(m_byBuff, m_byBuff.Length, 0, SocketFlags.None, new AsyncCallback(OnRecieve), socket);
        }

        public void SendMessage(string message)
        {
            throw new NotImplementedException();
        }

        public void SendMessage(GameState move)
        {
            foreach (var clientsSocket in ClientsSockets)
            {
                var json = JsonConvert.SerializeObject(move);

                var netStream = new NetworkStream(ServerSocket, true);
                var bf = new BinaryFormatter();
                var ms = new MemoryStream();
                bf.Serialize(ms, json);
                netStream.Write(ms.ToArray(), 0, ms.ToArray().Length);
            }
        }
    }
}
